package com.itranswarp.learnjava.service;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
// @scope("prototype")意思：每次从容器中获取Bean时，都会创建一个新的Bean。
// @scope("singleton")意思：每次从容器中获取Bean时，都会返回同一个Bean。
// @scope("prototype")和@scope("singleton")是Spring框架中定义的两个注解，用于指定Bean的作用域。
// @scope("prototype")表示每次从容器中获取Bean时，都会创建一个新的Bean。
// @scope("singleton")表示每次从容器中获取Bean时，都会返回同一个Bean。

import jakarta.annotation.PostConstruct;

// 在Spring中，如果不添加 @Scope 注解，Bean默认是单例模式（Singleton）。
// ## Spring Bean的默认作用域
// 在Spring框架中，Bean的默认作用域是单例（Singleton），这意味着：
// 1.容器中只会创建该Bean的一个实例
// 2.所有对该Bean的请求都会返回同一个实例
// 3.Bean在容器启动时就会被创建（除非设置了懒加载）
// 4. Bean会一直存在，直到容器被销毁

// 在 Spring 容器启动时，对于单例（Singleton）的 bean：
// - Spring 会在容器初始化时就创建这个 bean,并且实例化它
// - 这时就会调用 MailSession 的构造函数-因此构造函数中的 System.out.println("new MailSession()")会被执行

// 如果把注解改为 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) ：
//- 则只有在实际获取这个 bean 的时候才会创建实例
//- 每次获取都会创建新的实例
//- 打印语句也会在每次获取时执行

@Component
// @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class MailSession {

    public MailSession() {
        System.out.println("new MailSession()");
    }

    @PostConstruct
    public void init() {
        System.out.println("PostConstruct init MailSession");
    }
}
